package com.wh1200.mybatis.xmlless.resolver

import com.wh1200.mybatis.xmlless.config.BaseResolverTest
import com.wh1200.mybatis.xmlless.enums.XmllessDbType
import com.wh1200.mybatis.xmlless.replaceSpace
import com.wh1200.xmlless.test.dao.StudentDAO
import com.wh1200.xmlless.test.model.Student
import org.junit.jupiter.api.DisplayName
import org.junit.jupiter.api.Test
import kotlin.reflect.jvm.javaMethod
import kotlin.test.assertContains
import kotlin.test.assertEquals
import kotlin.test.assertNotNull

/**
 *
 * @author 吴昊
 * @date 2023/12/12 11:30
 * @since v0.0.0
 * @version 1.0
 */
@DisplayName("测试额外添加的join")
class JoinOnQueryResolverTest : BaseResolverTest(StudentDAO::class.java) {

  @Test
  @DisplayName("解析通过注解添加额外的join，并从join的表中获取字段")
  fun resolveExtraJoins() {
    val q = createQueryForMethod(StudentDAO::findDate.javaMethod!!)
    q.exception?.printStackTrace()
    val sql = q.sql
    assertNotNull(sql)
    if (dbType == XmllessDbType.MYSQL) {
      assertContains(
          sql.replaceSpace(), "GROUP BY DATE_FORMAT(t_student.create_time, '%Y-%m-%d')"
      )
    } else if (dbType == XmllessDbType.POSTGRE_SQL) {
      assertContains(
          sql.replaceSpace(), "GROUP BY TO_CHAR(t_student.create_time, 'YYYY-MM-DD')"
      )
    }

    assertContains(sql.replaceSpace(), "SELECT dateConfig.single_date")
    assertContains(
        sql,
        "date_format(dateConfig.single_date, '%Y-%m-%d') = date_format(t_student.create_time, '%Y-%m-%d')"
    )
  }

  @Test
  @DisplayName("JOIN ON 条件多于1个")
  fun multipleJoinOnConditions() {
    val q = createQueryForMethod(StudentDAO::findDate3.javaMethod!!)
    val sql = q.sql
    assertNotNull(sql)
  }

  @Test
  @DisplayName("交换on两边的表达式")
  fun resolveExtraJoinsSwitchOn() {
    val q = createQueryForMethod(StudentDAO::findDate2.javaMethod!!)
    q.exception?.printStackTrace()
    val sql = q.sql
    assertNotNull(sql)
    assertContains(
        sql.replaceSpace(), "GROUP BY date_format(t_student.create_time, '%Y-%m-%d')"
    )
    assertContains(
        sql.replaceSpace(), "SELECT dateConfig.single_date"
    )
    val tables = q.query?.containedTables()
    val from = q.query?.resolveFrom()
    assertNotNull(from)
    assertNotNull(tables)
    assertContains(tables, "createUser")
    assertContains(tables, "dateConfig")
    assertEquals(2, from.joins.size)
    assertContains(sql, "createUser.id = t_student.create_user_id")
    assertContains(sql, "createUser.department_id = 22")
    assertContains(
        sql,
        "date_format(dateConfig.single_date, '%Y-%m-%d') = date_format(t_student.create_time, '%Y-%m-%d')"
    )
  }

}
